<script setup lang="ts">
import { ref, nextTick } from 'vue'

const visible = ref(false)
const menuRef = ref<HTMLDivElement>()
const msgData = ref()

function open(e: MouseEvent, data: any) {
  visible.value = true
  msgData.value = data
  nextTick(() => {
    setMenu(e.y, e.x)
  })

  document.addEventListener(
    'mouseup',
    (event) => {
      if (menuRef.value && event.target instanceof Node && !menuRef.value.contains(event.target)) {
        visible.value = false
      }
    },
    { once: true }
  )
}

function setMenu(top_: number, left_: number) {
  if (!menuRef.value) return

  const largestHeight = window.innerHeight - menuRef.value.offsetHeight - 64
  const largestWidth = window.innerWidth - menuRef.value.offsetWidth - 25
  if (top_ > largestHeight) top_ = largestHeight
  if (left_ > largestWidth) left_ = largestWidth

  menuRef.value.style.top = top_ + 'px'
  menuRef.value.style.left = left_ + 'px'
}

defineExpose({ open })
</script>

<template>
  <div v-if="visible" ref="menuRef" class="menu" @click="visible = false">
    <slot :data="msgData"></slot>
  </div>
</template>

<style lang="less" scoped>
.menu {
  position: fixed;
  min-width: 136px;
  max-width: 240px;
  list-style: none;
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 6px 12px -4px rgba(0, 0, 0, 0.08);
  border: 1px solid rgba(0, 0, 0, 0.06);
  backdrop-filter: blur(12px);
  border-radius: 12px;
  box-sizing: border-box;
  padding: 6px;
  z-index: 1000;
  -webkit-app-region: no-drag;
  transition:
    background 125ms ease-out,
    opacity 125ms ease-out,
    transform 125ms ease-out;

  &:focus {
    outline: none;
  }
}

[data-theme='dark'] {
  .menu {
    background: rgba(36, 36, 36, 0.78);
    backdrop-filter: blur(16px) contrast(120%) brightness(60%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 0 6px rgba(255, 255, 255, 0.08);

    &:deep(.item):hover {
      color: var(--color-text);
    }
  }
}

.menu {
  &:deep(.item) {
    font-weight: 600;
    font-size: 14px;
    padding: 10px 14px;
    border-radius: 8px;
    cursor: default;
    color: var(--color-text);
    display: flex;
    align-items: center;

    &:hover {
      color: var(--color-primary);
      background: var(--color-primary-bg-for-transparent);
      transition:
        opacity 125ms ease-out,
        transform 125ms ease-out;
    }

    &:active {
      opacity: 0.75;
      transform: scale(0.95);
    }

    .svg-icon {
      height: 20px;
      width: 20px;
      margin-right: 5px;
    }
  }

  &:deep(hr) {
    margin: 4px 10px;
    background: rgba(128, 128, 128, 0.18);
    height: 1px;
    box-shadow: none;
    border: none;
  }
}
</style>
